home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Ubuntu 9.10 PL / karmelkowy-koliberek-desktop-9.10-i386-PL.iso / casper / filesystem.squashfs / usr / lib / python2.6 / aifc.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2009-11-11  |  29KB  |  1,035 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. '''Stuff to parse AIFF-C and AIFF files.
  5.  
  6. Unless explicitly stated otherwise, the description below is true
  7. both for AIFF-C files and AIFF files.
  8.  
  9. An AIFF-C file has the following structure.
  10.  
  11.   +-----------------+
  12.   | FORM            |
  13.   +-----------------+
  14.   | <size>          |
  15.   +----+------------+
  16.   |    | AIFC       |
  17.   |    +------------+
  18.   |    | <chunks>   |
  19.   |    |    .       |
  20.   |    |    .       |
  21.   |    |    .       |
  22.   +----+------------+
  23.  
  24. An AIFF file has the string "AIFF" instead of "AIFC".
  25.  
  26. A chunk consists of an identifier (4 bytes) followed by a size (4 bytes,
  27. big endian order), followed by the data.  The size field does not include
  28. the size of the 8 byte header.
  29.  
  30. The following chunk types are recognized.
  31.  
  32.   FVER
  33.       <version number of AIFF-C defining document> (AIFF-C only).
  34.   MARK
  35.       <# of markers> (2 bytes)
  36.       list of markers:
  37.           <marker ID> (2 bytes, must be > 0)
  38.           <position> (4 bytes)
  39.           <marker name> ("pstring")
  40.   COMM
  41.       <# of channels> (2 bytes)
  42.       <# of sound frames> (4 bytes)
  43.       <size of the samples> (2 bytes)
  44.       <sampling frequency> (10 bytes, IEEE 80-bit extended
  45.           floating point)
  46.       in AIFF-C files only:
  47.       <compression type> (4 bytes)
  48.       <human-readable version of compression type> ("pstring")
  49.   SSND
  50.       <offset> (4 bytes, not used by this program)
  51.       <blocksize> (4 bytes, not used by this program)
  52.       <sound data>
  53.  
  54. A pstring consists of 1 byte length, a string of characters, and 0 or 1
  55. byte pad to make the total length even.
  56.  
  57. Usage.
  58.  
  59. Reading AIFF files:
  60.   f = aifc.open(file, \'r\')
  61. where file is either the name of a file or an open file pointer.
  62. The open file pointer must have methods read(), seek(), and close().
  63. In some types of audio files, if the setpos() method is not used,
  64. the seek() method is not necessary.
  65.  
  66. This returns an instance of a class with the following public methods:
  67.   getnchannels()  -- returns number of audio channels (1 for
  68.              mono, 2 for stereo)
  69.   getsampwidth()  -- returns sample width in bytes
  70.   getframerate()  -- returns sampling frequency
  71.   getnframes()    -- returns number of audio frames
  72.   getcomptype()   -- returns compression type (\'NONE\' for AIFF files)
  73.   getcompname()   -- returns human-readable version of
  74.              compression type (\'not compressed\' for AIFF files)
  75.   getparams() -- returns a tuple consisting of all of the
  76.              above in the above order
  77.   getmarkers()    -- get the list of marks in the audio file or None
  78.              if there are no marks
  79.   getmark(id) -- get mark with the specified id (raises an error
  80.              if the mark does not exist)
  81.   readframes(n)   -- returns at most n frames of audio
  82.   rewind()    -- rewind to the beginning of the audio stream
  83.   setpos(pos) -- seek to the specified position
  84.   tell()      -- return the current position
  85.   close()     -- close the instance (make it unusable)
  86. The position returned by tell(), the position given to setpos() and
  87. the position of marks are all compatible and have nothing to do with
  88. the actual position in the file.
  89. The close() method is called automatically when the class instance
  90. is destroyed.
  91.  
  92. Writing AIFF files:
  93.   f = aifc.open(file, \'w\')
  94. where file is either the name of a file or an open file pointer.
  95. The open file pointer must have methods write(), tell(), seek(), and
  96. close().
  97.  
  98. This returns an instance of a class with the following public methods:
  99.   aiff()      -- create an AIFF file (AIFF-C default)
  100.   aifc()      -- create an AIFF-C file
  101.   setnchannels(n) -- set the number of channels
  102.   setsampwidth(n) -- set the sample width
  103.   setframerate(n) -- set the frame rate
  104.   setnframes(n)   -- set the number of frames
  105.   setcomptype(type, name)
  106.           -- set the compression type and the
  107.              human-readable compression type
  108.   setparams(tuple)
  109.           -- set all parameters at once
  110.   setmark(id, pos, name)
  111.           -- add specified mark to the list of marks
  112.   tell()      -- return current position in output file (useful
  113.              in combination with setmark())
  114.   writeframesraw(data)
  115.           -- write audio frames without pathing up the
  116.              file header
  117.   writeframes(data)
  118.           -- write audio frames and patch up the file header
  119.   close()     -- patch up the file header and close the
  120.              output file
  121. You should set the parameters before the first writeframesraw or
  122. writeframes.  The total number of frames does not need to be set,
  123. but when it is set to the correct value, the header does not have to
  124. be patched up.
  125. It is best to first set all parameters, perhaps possibly the
  126. compression type, and then write audio frames using writeframesraw.
  127. When all frames have been written, either call writeframes(\'\') or
  128. close() to patch up the sizes in the header.
  129. Marks can be added anytime.  If there are any marks, ypu must call
  130. close() after all frames have been written.
  131. The close() method is called automatically when the class instance
  132. is destroyed.
  133.  
  134. When a file is opened with the extension \'.aiff\', an AIFF file is
  135. written, otherwise an AIFF-C file is written.  This default can be
  136. changed by calling aiff() or aifc() before the first writeframes or
  137. writeframesraw.
  138. '''
  139. import struct
  140. import __builtin__
  141. __all__ = [
  142.     'Error',
  143.     'open',
  144.     'openfp']
  145.  
  146. class Error(Exception):
  147.     pass
  148.  
  149. _AIFC_version = 0xA2805140L
  150.  
  151. def _read_long(file):
  152.     
  153.     try:
  154.         return struct.unpack('>l', file.read(4))[0]
  155.     except struct.error:
  156.         raise EOFError
  157.  
  158.  
  159.  
  160. def _read_ulong(file):
  161.     
  162.     try:
  163.         return struct.unpack('>L', file.read(4))[0]
  164.     except struct.error:
  165.         raise EOFError
  166.  
  167.  
  168.  
  169. def _read_short(file):
  170.     
  171.     try:
  172.         return struct.unpack('>h', file.read(2))[0]
  173.     except struct.error:
  174.         raise EOFError
  175.  
  176.  
  177.  
  178. def _read_string(file):
  179.     length = ord(file.read(1))
  180.     if length == 0:
  181.         data = ''
  182.     else:
  183.         data = file.read(length)
  184.     if length & 1 == 0:
  185.         dummy = file.read(1)
  186.     
  187.     return data
  188.  
  189. _HUGE_VAL = 1.79769e+308
  190.  
  191. def _read_float(f):
  192.     expon = _read_short(f)
  193.     sign = 1
  194.     if expon < 0:
  195.         sign = -1
  196.         expon = expon + 32768
  197.     
  198.     himant = _read_ulong(f)
  199.     lomant = _read_ulong(f)
  200.     if himant == himant and lomant == lomant:
  201.         pass
  202.     elif lomant == 0:
  203.         f = 0
  204.     elif expon == 32767:
  205.         f = _HUGE_VAL
  206.     else:
  207.         expon = expon - 16383
  208.         f = (himant * 0x100000000L + lomant) * pow(2, expon - 63)
  209.     return sign * f
  210.  
  211.  
  212. def _write_short(f, x):
  213.     f.write(struct.pack('>h', x))
  214.  
  215.  
  216. def _write_long(f, x):
  217.     f.write(struct.pack('>L', x))
  218.  
  219.  
  220. def _write_string(f, s):
  221.     if len(s) > 255:
  222.         raise ValueError('string exceeds maximum pstring length')
  223.     len(s) > 255
  224.     f.write(chr(len(s)))
  225.     f.write(s)
  226.     if len(s) & 1 == 0:
  227.         f.write(chr(0))
  228.     
  229.  
  230.  
  231. def _write_float(f, x):
  232.     import math as math
  233.     if x < 0:
  234.         sign = 32768
  235.         x = x * -1
  236.     else:
  237.         sign = 0
  238.     if x == 0:
  239.         expon = 0
  240.         himant = 0
  241.         lomant = 0
  242.     else:
  243.         (fmant, expon) = math.frexp(x)
  244.         if expon > 16384 or fmant >= 1:
  245.             expon = sign | 32767
  246.             himant = 0
  247.             lomant = 0
  248.         else:
  249.             expon = expon + 16382
  250.             if expon < 0:
  251.                 fmant = math.ldexp(fmant, expon)
  252.                 expon = 0
  253.             
  254.             expon = expon | sign
  255.             fmant = math.ldexp(fmant, 32)
  256.             fsmant = math.floor(fmant)
  257.             himant = long(fsmant)
  258.             fmant = math.ldexp(fmant - fsmant, 32)
  259.             fsmant = math.floor(fmant)
  260.             lomant = long(fsmant)
  261.     _write_short(f, expon)
  262.     _write_long(f, himant)
  263.     _write_long(f, lomant)
  264.  
  265. from chunk import Chunk
  266.  
  267. class Aifc_read:
  268.     
  269.     def initfp(self, file):
  270.         self._version = 0
  271.         self._decomp = None
  272.         self._convert = None
  273.         self._markers = []
  274.         self._soundpos = 0
  275.         self._file = file
  276.         chunk = Chunk(file)
  277.         if chunk.getname() != 'FORM':
  278.             raise Error, 'file does not start with FORM id'
  279.         chunk.getname() != 'FORM'
  280.         formdata = chunk.read(4)
  281.         if formdata == 'AIFF':
  282.             self._aifc = 0
  283.         elif formdata == 'AIFC':
  284.             self._aifc = 1
  285.         else:
  286.             raise Error, 'not an AIFF or AIFF-C file'
  287.         self._comm_chunk_read = formdata == 'AIFF'
  288.         while None:
  289.             self._ssnd_seek_needed = 1
  290.             
  291.             try:
  292.                 chunk = Chunk(self._file)
  293.             except EOFError:
  294.                 break
  295.  
  296.             chunkname = chunk.getname()
  297.             if chunkname == 'COMM':
  298.                 self._read_comm_chunk(chunk)
  299.                 self._comm_chunk_read = 1
  300.             elif chunkname == 'SSND':
  301.                 self._ssnd_chunk = chunk
  302.                 dummy = chunk.read(8)
  303.                 self._ssnd_seek_needed = 0
  304.             elif chunkname == 'FVER':
  305.                 self._version = _read_ulong(chunk)
  306.             elif chunkname == 'MARK':
  307.                 self._readmark(chunk)
  308.             
  309.             continue
  310.             if not (self._comm_chunk_read) or not (self._ssnd_chunk):
  311.                 raise Error, 'COMM chunk and/or SSND chunk missing'
  312.             not (self._ssnd_chunk)
  313.             if self._aifc and self._decomp:
  314.                 import cl as cl
  315.                 params = [
  316.                     cl.ORIGINAL_FORMAT,
  317.                     0,
  318.                     cl.BITS_PER_COMPONENT,
  319.                     self._sampwidth * 8,
  320.                     cl.FRAME_RATE,
  321.                     self._framerate]
  322.                 if self._nchannels == 1:
  323.                     params[1] = cl.MONO
  324.                 elif self._nchannels == 2:
  325.                     params[1] = cl.STEREO_INTERLEAVED
  326.                 else:
  327.                     raise Error, 'cannot compress more than 2 channels'
  328.                 (self._nchannels == 1)._decomp.SetParams(params)
  329.             
  330.  
  331.     
  332.     def __init__(self, f):
  333.         if type(f) == type(''):
  334.             f = __builtin__.open(f, 'rb')
  335.         
  336.         self.initfp(f)
  337.  
  338.     
  339.     def getfp(self):
  340.         return self._file
  341.  
  342.     
  343.     def rewind(self):
  344.         self._ssnd_seek_needed = 1
  345.         self._soundpos = 0
  346.  
  347.     
  348.     def close(self):
  349.         if self._decomp:
  350.             self._decomp.CloseDecompressor()
  351.             self._decomp = None
  352.         
  353.         self._file.close()
  354.  
  355.     
  356.     def tell(self):
  357.         return self._soundpos
  358.  
  359.     
  360.     def getnchannels(self):
  361.         return self._nchannels
  362.  
  363.     
  364.     def getnframes(self):
  365.         return self._nframes
  366.  
  367.     
  368.     def getsampwidth(self):
  369.         return self._sampwidth
  370.  
  371.     
  372.     def getframerate(self):
  373.         return self._framerate
  374.  
  375.     
  376.     def getcomptype(self):
  377.         return self._comptype
  378.  
  379.     
  380.     def getcompname(self):
  381.         return self._compname
  382.  
  383.     
  384.     def getparams(self):
  385.         return (self.getnchannels(), self.getsampwidth(), self.getframerate(), self.getnframes(), self.getcomptype(), self.getcompname())
  386.  
  387.     
  388.     def getmarkers(self):
  389.         if len(self._markers) == 0:
  390.             return None
  391.         return self._markers
  392.  
  393.     
  394.     def getmark(self, id):
  395.         for marker in self._markers:
  396.             if id == marker[0]:
  397.                 return marker
  398.         
  399.         raise Error, 'marker %r does not exist' % (id,)
  400.  
  401.     
  402.     def setpos(self, pos):
  403.         if pos < 0 or pos > self._nframes:
  404.             raise Error, 'position not in range'
  405.         pos > self._nframes
  406.         self._soundpos = pos
  407.         self._ssnd_seek_needed = 1
  408.  
  409.     
  410.     def readframes(self, nframes):
  411.         if self._ssnd_seek_needed:
  412.             self._ssnd_chunk.seek(0)
  413.             dummy = self._ssnd_chunk.read(8)
  414.             pos = self._soundpos * self._framesize
  415.             if pos:
  416.                 self._ssnd_chunk.seek(pos + 8)
  417.             
  418.             self._ssnd_seek_needed = 0
  419.         
  420.         if nframes == 0:
  421.             return ''
  422.         data = self._ssnd_chunk.read(nframes * self._framesize)
  423.         if self._convert and data:
  424.             data = self._convert(data)
  425.         
  426.         self._soundpos = self._soundpos + len(data) / self._nchannels * self._sampwidth
  427.         return data
  428.  
  429.     
  430.     def _decomp_data(self, data):
  431.         import cl
  432.         dummy = self._decomp.SetParam(cl.FRAME_BUFFER_SIZE, len(data) * 2)
  433.         return self._decomp.Decompress(len(data) / self._nchannels, data)
  434.  
  435.     
  436.     def _ulaw2lin(self, data):
  437.         import audioop as audioop
  438.         return audioop.ulaw2lin(data, 2)
  439.  
  440.     
  441.     def _adpcm2lin(self, data):
  442.         import audioop
  443.         if not hasattr(self, '_adpcmstate'):
  444.             self._adpcmstate = None
  445.         
  446.         (data, self._adpcmstate) = audioop.adpcm2lin(data, 2, self._adpcmstate)
  447.         return data
  448.  
  449.     
  450.     def _read_comm_chunk(self, chunk):
  451.         self._nchannels = _read_short(chunk)
  452.         self._nframes = _read_long(chunk)
  453.         self._sampwidth = (_read_short(chunk) + 7) / 8
  454.         self._framerate = int(_read_float(chunk))
  455.         self._framesize = self._nchannels * self._sampwidth
  456.         if self._aifc:
  457.             kludge = 0
  458.             if chunk.chunksize == 18:
  459.                 kludge = 1
  460.                 print 'Warning: bad COMM chunk size'
  461.                 chunk.chunksize = 23
  462.             
  463.             self._comptype = chunk.read(4)
  464.             if kludge:
  465.                 length = ord(chunk.file.read(1))
  466.                 if length & 1 == 0:
  467.                     length = length + 1
  468.                 
  469.                 chunk.chunksize = chunk.chunksize + length
  470.                 chunk.file.seek(-1, 1)
  471.             
  472.             self._compname = _read_string(chunk)
  473.             if self._comptype != 'NONE':
  474.                 if self._comptype == 'G722':
  475.                     
  476.                     try:
  477.                         import audioop
  478.                     except ImportError:
  479.                         pass
  480.  
  481.                     self._convert = self._adpcm2lin
  482.                     self._framesize = self._framesize / 4
  483.                     return None
  484.                 self._comptype == 'G722'
  485.                 
  486.                 try:
  487.                     import cl
  488.                 except ImportError:
  489.                     if self._comptype == 'ULAW':
  490.                         
  491.                         try:
  492.                             import audioop
  493.                             self._convert = self._ulaw2lin
  494.                             self._framesize = self._framesize / 2
  495.                             return None
  496.                         except ImportError:
  497.                             pass
  498.                         except:
  499.                             None<EXCEPTION MATCH>ImportError
  500.                         
  501.  
  502.                     None<EXCEPTION MATCH>ImportError
  503.                     raise Error, 'cannot read compressed AIFF-C files'
  504.  
  505.                 if self._comptype == 'ULAW':
  506.                     scheme = cl.G711_ULAW
  507.                     self._framesize = self._framesize / 2
  508.                 elif self._comptype == 'ALAW':
  509.                     scheme = cl.G711_ALAW
  510.                     self._framesize = self._framesize / 2
  511.                 else:
  512.                     raise Error, 'unsupported compression type'
  513.                 self._decomp = (self._comptype == 'ULAW').OpenDecompressor(scheme)
  514.                 self._convert = self._decomp_data
  515.             
  516.         else:
  517.             self._comptype = 'NONE'
  518.             self._compname = 'not compressed'
  519.  
  520.     
  521.     def _readmark(self, chunk):
  522.         nmarkers = _read_short(chunk)
  523.         
  524.         try:
  525.             for i in range(nmarkers):
  526.                 id = _read_short(chunk)
  527.                 pos = _read_long(chunk)
  528.                 name = _read_string(chunk)
  529.                 if pos or name:
  530.                     self._markers.append((id, pos, name))
  531.                     continue
  532.         except EOFError:
  533.             print 'Warning: MARK chunk contains only', len(self._markers),
  534.             if len(self._markers) == 1:
  535.                 print 'marker',
  536.             else:
  537.                 print 'markers',
  538.             print 'instead of', nmarkers
  539.  
  540.  
  541.  
  542.  
  543. class Aifc_write:
  544.     
  545.     def __init__(self, f):
  546.         if type(f) == type(''):
  547.             filename = f
  548.             f = __builtin__.open(f, 'wb')
  549.         else:
  550.             filename = '???'
  551.         self.initfp(f)
  552.         if filename[-5:] == '.aiff':
  553.             self._aifc = 0
  554.         else:
  555.             self._aifc = 1
  556.  
  557.     
  558.     def initfp(self, file):
  559.         self._file = file
  560.         self._version = _AIFC_version
  561.         self._comptype = 'NONE'
  562.         self._compname = 'not compressed'
  563.         self._comp = None
  564.         self._convert = None
  565.         self._nchannels = 0
  566.         self._sampwidth = 0
  567.         self._framerate = 0
  568.         self._nframes = 0
  569.         self._nframeswritten = 0
  570.         self._datawritten = 0
  571.         self._datalength = 0
  572.         self._markers = []
  573.         self._marklength = 0
  574.         self._aifc = 1
  575.  
  576.     
  577.     def __del__(self):
  578.         if self._file:
  579.             self.close()
  580.         
  581.  
  582.     
  583.     def aiff(self):
  584.         if self._nframeswritten:
  585.             raise Error, 'cannot change parameters after starting to write'
  586.         self._nframeswritten
  587.         self._aifc = 0
  588.  
  589.     
  590.     def aifc(self):
  591.         if self._nframeswritten:
  592.             raise Error, 'cannot change parameters after starting to write'
  593.         self._nframeswritten
  594.         self._aifc = 1
  595.  
  596.     
  597.     def setnchannels(self, nchannels):
  598.         if self._nframeswritten:
  599.             raise Error, 'cannot change parameters after starting to write'
  600.         self._nframeswritten
  601.         if nchannels < 1:
  602.             raise Error, 'bad # of channels'
  603.         nchannels < 1
  604.         self._nchannels = nchannels
  605.  
  606.     
  607.     def getnchannels(self):
  608.         if not self._nchannels:
  609.             raise Error, 'number of channels not set'
  610.         self._nchannels
  611.         return self._nchannels
  612.  
  613.     
  614.     def setsampwidth(self, sampwidth):
  615.         if self._nframeswritten:
  616.             raise Error, 'cannot change parameters after starting to write'
  617.         self._nframeswritten
  618.         if sampwidth < 1 or sampwidth > 4:
  619.             raise Error, 'bad sample width'
  620.         sampwidth > 4
  621.         self._sampwidth = sampwidth
  622.  
  623.     
  624.     def getsampwidth(self):
  625.         if not self._sampwidth:
  626.             raise Error, 'sample width not set'
  627.         self._sampwidth
  628.         return self._sampwidth
  629.  
  630.     
  631.     def setframerate(self, framerate):
  632.         if self._nframeswritten:
  633.             raise Error, 'cannot change parameters after starting to write'
  634.         self._nframeswritten
  635.         if framerate <= 0:
  636.             raise Error, 'bad frame rate'
  637.         framerate <= 0
  638.         self._framerate = framerate
  639.  
  640.     
  641.     def getframerate(self):
  642.         if not self._framerate:
  643.             raise Error, 'frame rate not set'
  644.         self._framerate
  645.         return self._framerate
  646.  
  647.     
  648.     def setnframes(self, nframes):
  649.         if self._nframeswritten:
  650.             raise Error, 'cannot change parameters after starting to write'
  651.         self._nframeswritten
  652.         self._nframes = nframes
  653.  
  654.     
  655.     def getnframes(self):
  656.         return self._nframeswritten
  657.  
  658.     
  659.     def setcomptype(self, comptype, compname):
  660.         if self._nframeswritten:
  661.             raise Error, 'cannot change parameters after starting to write'
  662.         self._nframeswritten
  663.         if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
  664.             raise Error, 'unsupported compression type'
  665.         comptype not in ('NONE', 'ULAW', 'ALAW', 'G722')
  666.         self._comptype = comptype
  667.         self._compname = compname
  668.  
  669.     
  670.     def getcomptype(self):
  671.         return self._comptype
  672.  
  673.     
  674.     def getcompname(self):
  675.         return self._compname
  676.  
  677.     
  678.     def setparams(self, info):
  679.         (nchannels, sampwidth, framerate, nframes, comptype, compname) = info
  680.         if self._nframeswritten:
  681.             raise Error, 'cannot change parameters after starting to write'
  682.         self._nframeswritten
  683.         if comptype not in ('NONE', 'ULAW', 'ALAW', 'G722'):
  684.             raise Error, 'unsupported compression type'
  685.         comptype not in ('NONE', 'ULAW', 'ALAW', 'G722')
  686.         self.setnchannels(nchannels)
  687.         self.setsampwidth(sampwidth)
  688.         self.setframerate(framerate)
  689.         self.setnframes(nframes)
  690.         self.setcomptype(comptype, compname)
  691.  
  692.     
  693.     def getparams(self):
  694.         if not (self._nchannels) and not (self._sampwidth) or not (self._framerate):
  695.             raise Error, 'not all parameters set'
  696.         not (self._framerate)
  697.         return (self._nchannels, self._sampwidth, self._framerate, self._nframes, self._comptype, self._compname)
  698.  
  699.     
  700.     def setmark(self, id, pos, name):
  701.         if id <= 0:
  702.             raise Error, 'marker ID must be > 0'
  703.         id <= 0
  704.         if pos < 0:
  705.             raise Error, 'marker position must be >= 0'
  706.         pos < 0
  707.         if type(name) != type(''):
  708.             raise Error, 'marker name must be a string'
  709.         type(name) != type('')
  710.         for i in range(len(self._markers)):
  711.             if id == self._markers[i][0]:
  712.                 self._markers[i] = (id, pos, name)
  713.                 return None
  714.         
  715.         self._markers.append((id, pos, name))
  716.  
  717.     
  718.     def getmark(self, id):
  719.         for marker in self._markers:
  720.             if id == marker[0]:
  721.                 return marker
  722.         
  723.         raise Error, 'marker %r does not exist' % (id,)
  724.  
  725.     
  726.     def getmarkers(self):
  727.         if len(self._markers) == 0:
  728.             return None
  729.         return self._markers
  730.  
  731.     
  732.     def tell(self):
  733.         return self._nframeswritten
  734.  
  735.     
  736.     def writeframesraw(self, data):
  737.         self._ensure_header_written(len(data))
  738.         nframes = len(data) / self._sampwidth * self._nchannels
  739.         if self._convert:
  740.             data = self._convert(data)
  741.         
  742.         self._file.write(data)
  743.         self._nframeswritten = self._nframeswritten + nframes
  744.         self._datawritten = self._datawritten + len(data)
  745.  
  746.     
  747.     def writeframes(self, data):
  748.         self.writeframesraw(data)
  749.         if self._nframeswritten != self._nframes or self._datalength != self._datawritten:
  750.             self._patchheader()
  751.         
  752.  
  753.     
  754.     def close(self):
  755.         self._ensure_header_written(0)
  756.         if self._datawritten & 1:
  757.             self._file.write(chr(0))
  758.             self._datawritten = self._datawritten + 1
  759.         
  760.         self._writemarkers()
  761.         if self._nframeswritten != self._nframes and self._datalength != self._datawritten or self._marklength:
  762.             self._patchheader()
  763.         
  764.         if self._comp:
  765.             self._comp.CloseCompressor()
  766.             self._comp = None
  767.         
  768.         self._file.close()
  769.  
  770.     
  771.     def _comp_data(self, data):
  772.         import cl
  773.         dummy = self._comp.SetParam(cl.FRAME_BUFFER_SIZE, len(data))
  774.         dummy = self._comp.SetParam(cl.COMPRESSED_BUFFER_SIZE, len(data))
  775.         return self._comp.Compress(self._nframes, data)
  776.  
  777.     
  778.     def _lin2ulaw(self, data):
  779.         import audioop
  780.         return audioop.lin2ulaw(data, 2)
  781.  
  782.     
  783.     def _lin2adpcm(self, data):
  784.         import audioop
  785.         if not hasattr(self, '_adpcmstate'):
  786.             self._adpcmstate = None
  787.         
  788.         (data, self._adpcmstate) = audioop.lin2adpcm(data, 2, self._adpcmstate)
  789.         return data
  790.  
  791.     
  792.     def _ensure_header_written(self, datasize):
  793.         if not self._nframeswritten:
  794.             if self._comptype in ('ULAW', 'ALAW'):
  795.                 if not self._sampwidth:
  796.                     self._sampwidth = 2
  797.                 
  798.                 if self._sampwidth != 2:
  799.                     raise Error, 'sample width must be 2 when compressing with ULAW or ALAW'
  800.                 self._sampwidth != 2
  801.             
  802.             if self._comptype == 'G722':
  803.                 if not self._sampwidth:
  804.                     self._sampwidth = 2
  805.                 
  806.                 if self._sampwidth != 2:
  807.                     raise Error, 'sample width must be 2 when compressing with G7.22 (ADPCM)'
  808.                 self._sampwidth != 2
  809.             
  810.             if not self._nchannels:
  811.                 raise Error, '# channels not specified'
  812.             self._nchannels
  813.             if not self._sampwidth:
  814.                 raise Error, 'sample width not specified'
  815.             self._sampwidth
  816.             if not self._framerate:
  817.                 raise Error, 'sampling rate not specified'
  818.             self._framerate
  819.             self._write_header(datasize)
  820.         
  821.  
  822.     
  823.     def _init_compression(self):
  824.         if self._comptype == 'G722':
  825.             self._convert = self._lin2adpcm
  826.             return None
  827.         
  828.         try:
  829.             import cl
  830.         except ImportError:
  831.             self._comptype == 'G722'
  832.             self._comptype == 'G722'
  833.             if self._comptype == 'ULAW':
  834.                 
  835.                 try:
  836.                     import audioop
  837.                     self._convert = self._lin2ulaw
  838.                     return None
  839.                 except ImportError:
  840.                     pass
  841.                 except:
  842.                     None<EXCEPTION MATCH>ImportError
  843.                 
  844.  
  845.             None<EXCEPTION MATCH>ImportError
  846.             raise Error, 'cannot write compressed AIFF-C files'
  847.         except:
  848.             self._comptype == 'G722'
  849.  
  850.         if self._comptype == 'ULAW':
  851.             scheme = cl.G711_ULAW
  852.         elif self._comptype == 'ALAW':
  853.             scheme = cl.G711_ALAW
  854.         else:
  855.             raise Error, 'unsupported compression type'
  856.         self._comp = (self._comptype == 'G722').OpenCompressor(scheme)
  857.         params = [
  858.             cl.ORIGINAL_FORMAT,
  859.             0,
  860.             cl.BITS_PER_COMPONENT,
  861.             self._sampwidth * 8,
  862.             cl.FRAME_RATE,
  863.             self._framerate,
  864.             cl.FRAME_BUFFER_SIZE,
  865.             100,
  866.             cl.COMPRESSED_BUFFER_SIZE,
  867.             100]
  868.         if self._nchannels == 1:
  869.             params[1] = cl.MONO
  870.         elif self._nchannels == 2:
  871.             params[1] = cl.STEREO_INTERLEAVED
  872.         else:
  873.             raise Error, 'cannot compress more than 2 channels'
  874.         (self._nchannels == 1)._comp.SetParams(params)
  875.         dummy = self._comp.Compress(0, '')
  876.         self._convert = self._comp_data
  877.  
  878.     
  879.     def _write_header(self, initlength):
  880.         if self._aifc and self._comptype != 'NONE':
  881.             self._init_compression()
  882.         
  883.         self._file.write('FORM')
  884.         if not self._nframes:
  885.             self._nframes = initlength / self._nchannels * self._sampwidth
  886.         
  887.         self._datalength = self._nframes * self._nchannels * self._sampwidth
  888.         if self._datalength & 1:
  889.             self._datalength = self._datalength + 1
  890.         
  891.         if self._aifc:
  892.             if self._comptype in ('ULAW', 'ALAW'):
  893.                 self._datalength = self._datalength / 2
  894.                 if self._datalength & 1:
  895.                     self._datalength = self._datalength + 1
  896.                 
  897.             elif self._comptype == 'G722':
  898.                 self._datalength = (self._datalength + 3) / 4
  899.                 if self._datalength & 1:
  900.                     self._datalength = self._datalength + 1
  901.                 
  902.             
  903.         
  904.         self._form_length_pos = self._file.tell()
  905.         commlength = self._write_form_length(self._datalength)
  906.         if self._aifc:
  907.             self._file.write('AIFC')
  908.             self._file.write('FVER')
  909.             _write_long(self._file, 4)
  910.             _write_long(self._file, self._version)
  911.         else:
  912.             self._file.write('AIFF')
  913.         self._file.write('COMM')
  914.         _write_long(self._file, commlength)
  915.         _write_short(self._file, self._nchannels)
  916.         self._nframes_pos = self._file.tell()
  917.         _write_long(self._file, self._nframes)
  918.         _write_short(self._file, self._sampwidth * 8)
  919.         _write_float(self._file, self._framerate)
  920.         if self._aifc:
  921.             self._file.write(self._comptype)
  922.             _write_string(self._file, self._compname)
  923.         
  924.         self._file.write('SSND')
  925.         self._ssnd_length_pos = self._file.tell()
  926.         _write_long(self._file, self._datalength + 8)
  927.         _write_long(self._file, 0)
  928.         _write_long(self._file, 0)
  929.  
  930.     
  931.     def _write_form_length(self, datalength):
  932.         if self._aifc:
  933.             commlength = 23 + len(self._compname)
  934.             if commlength & 1:
  935.                 commlength = commlength + 1
  936.             
  937.             verslength = 12
  938.         else:
  939.             commlength = 18
  940.             verslength = 0
  941.         _write_long(self._file, 4 + verslength + self._marklength + 8 + commlength + 16 + datalength)
  942.         return commlength
  943.  
  944.     
  945.     def _patchheader(self):
  946.         curpos = self._file.tell()
  947.         if self._datawritten & 1:
  948.             datalength = self._datawritten + 1
  949.             self._file.write(chr(0))
  950.         else:
  951.             datalength = self._datawritten
  952.         if datalength == self._datalength and self._nframes == self._nframeswritten and self._marklength == 0:
  953.             self._file.seek(curpos, 0)
  954.             return None
  955.         self._file.seek(self._form_length_pos, 0)
  956.         dummy = self._write_form_length(datalength)
  957.         self._file.seek(self._nframes_pos, 0)
  958.         _write_long(self._file, self._nframeswritten)
  959.         self._file.seek(self._ssnd_length_pos, 0)
  960.         _write_long(self._file, datalength + 8)
  961.         self._file.seek(curpos, 0)
  962.         self._nframes = self._nframeswritten
  963.         self._datalength = datalength
  964.  
  965.     
  966.     def _writemarkers(self):
  967.         if len(self._markers) == 0:
  968.             return None
  969.         self._file.write('MARK')
  970.         length = 2
  971.         for marker in self._markers:
  972.             (id, pos, name) = marker
  973.             length = length + len(name) + 1 + 6
  974.             if len(name) & 1 == 0:
  975.                 length = length + 1
  976.                 continue
  977.             len(self._markers) == 0
  978.         
  979.         _write_long(self._file, length)
  980.         self._marklength = length + 8
  981.         _write_short(self._file, len(self._markers))
  982.         for marker in self._markers:
  983.             (id, pos, name) = marker
  984.             _write_short(self._file, id)
  985.             _write_long(self._file, pos)
  986.             _write_string(self._file, name)
  987.         
  988.  
  989.  
  990.  
  991. def open(f, mode = None):
  992.     if mode is None:
  993.         if hasattr(f, 'mode'):
  994.             mode = f.mode
  995.         else:
  996.             mode = 'rb'
  997.     
  998.     if mode in ('r', 'rb'):
  999.         return Aifc_read(f)
  1000.     if mode in ('w', 'wb'):
  1001.         return Aifc_write(f)
  1002.     raise Error, "mode must be 'r', 'rb', 'w', or 'wb'"
  1003.  
  1004. openfp = open
  1005. if __name__ == '__main__':
  1006.     import sys
  1007.     if not sys.argv[1:]:
  1008.         sys.argv.append('/usr/demos/data/audio/bach.aiff')
  1009.     
  1010.     fn = sys.argv[1]
  1011.     f = open(fn, 'r')
  1012.     print 'Reading', fn
  1013.     print 'nchannels =', f.getnchannels()
  1014.     print 'nframes   =', f.getnframes()
  1015.     print 'sampwidth =', f.getsampwidth()
  1016.     print 'framerate =', f.getframerate()
  1017.     print 'comptype  =', f.getcomptype()
  1018.     print 'compname  =', f.getcompname()
  1019.     if sys.argv[2:]:
  1020.         gn = sys.argv[2]
  1021.         print 'Writing', gn
  1022.         g = open(gn, 'w')
  1023.         g.setparams(f.getparams())
  1024.         while None:
  1025.             data = f.readframes(1024)
  1026.             if not data:
  1027.                 break
  1028.             
  1029.             continue
  1030.             g.close()
  1031.             f.close()
  1032.             print 'Done.'
  1033.     sys.argv[2:]
  1034.  
  1035.